import Vue from "vue";
import VueRouter from "vue-router";
import routes from "./routes";
import store from "@/store";
console.log(store);

Vue.use(VueRouter);

const router = new VueRouter({
	mode: "history",
	routes: routes,
	//控制路由切换的时候,滚动条的位置
	scrollBehavior() {
		return {
			x: 0,
			y: 0,
		};
	},
});

//路由前置守卫进行 路由跳转的鉴权操作
//1.设置一个白名单,控制哪些路由不需要登录就可以访问的
const whitePath = [
	"login",
	"home",
	"register",
	"search",
	"detail",
	"addCartSuccess",
];

//2. 配置全局前置守卫
router.beforeEach(async (to, from, next) => {
	console.log(1);
	//从vuex中拿到token
	const token = store.state.user.token;
	//3.判断是否存在
	if (token) {
		console.log(2);
		//当token存在的时候
		//5.判断我们要去的地方是不是登录页,如果是则直接回到首页
		if (to.name === "login") {
			next("/home");
		} else {
			// 6.现在有token去的不是登录页,判断我们是否拥有用户信息(一般来说,登录只会返回token,然后我们一旦有token都会再次发送请求请求用户的详细信息)
			// console.log(store)
			const isUserInfo = !!store.state.user.userInfo.nickName;
			if (isUserInfo) {
				next(); //又有token 又有用户信息 则完全放行
			} else {
				//请求用户信息
				//异常处理,一旦刷新,token是持久化存的,用户信息不是持久化的,所以刷新以后一定会重新获取用户信息,一旦token过期或者token被篡改,则无法正常获取数据,此时应该清除掉已经报废的token,并且重新让用户登录
				try {
					//dispatch方法只是调用getUserInfo方法的一种方式,所以他的返回值和getUserInfo的返回值一致,都是返回promise实例
					await store.dispatch("user/getUserInfo"); // (小结:因为在user.js工具内书写的getUserInfo函数利用try,catch方法捕获reqUserInfo接口是否成功取值,如果是请求失败的情况,会直接使用catch弹出错误弹窗进行错误捕获处理(这种情景之前没见过),在这种情况下返回的promise对象永远为成功,所以最好的方法就是让其catch方法直接返回一个失败的promise来确保在这个这个情况下能拿到失败的promise对象,从而触发这里的catch错误捕获~~
					//一旦得到用户信息我们无条件放行
					next();
				} catch (e) {
					//如果获取用户信息异常,说明token已经不能用了,需要清掉重新登录
					store.dispatch("user/resetToken");
					next("/login"); //重新登录去吧
				}
			}
		}
	} else {
		//4.当token不存在的时候
		//判断当前去的路由地址是不是在白名单中,如果是则直接放行,如果不是则直接把导航定位到登录页
		if (whitePath.includes(to.name)) {
			console.log(3);
			next(); //放行
		} else {
			console.log(4);
			next("/login");
		}
	}
});

export default router;
